package eu.smoothit.sis.controller.iop.impl;

import java.util.List;

import javax.ejb.EJB;
import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;

import org.apache.log4j.Logger;

import eu.smoothit.sis.controller.iop.ActiveTorrent;
import eu.smoothit.sis.controller.iop.ActivityReport;
import eu.smoothit.sis.controller.iop.ActivityReportEntry;
import eu.smoothit.sis.controller.iop.ConfigParams;
import eu.smoothit.sis.controller.iop.IoPConfig;
import eu.smoothit.sis.controller.iop.IoPEndpoint;
import eu.smoothit.sis.controller.iop.ResponseEntry;
import eu.smoothit.sis.controller.iop.TorrentRating;
import eu.smoothit.sis.controller.iop.TorrentStat;

/**
 * IoP Web Service Endpoint using XDoclet
 * 
 * @author Michael Makidis, Sergios Soursos, Intracom Telecom
 * @version 1.0
 * 
 * @web.servlet 
 * 		name = "IoPEndpoint" 
 * 		display-name = "IoPEndpoint"
 * @web.servlet-mapping 
 * 		url-pattern = "/IoPEndpoint"                    
 */
@WebService(
		serviceName = "IoPService",
		endpointInterface = "eu.smoothit.sis.controller.iop.IoPEndpoint",
		targetNamespace = "http://iop.ws.sis.smoothit.eu/",
		portName = "IoPServicePort")
public class IoPEndpointImpl implements IoPEndpoint {
	
	/**
	 * The logger.
	 */
	private static org.apache.log4j.Logger log = Logger
			.getLogger(IoPEndpointImpl.class.getName());
	
	/**
	 * The Torrent Rating service
	 */
	@EJB
	protected TorrentRating rater;
	
	/**
	 * The IoP Configurator service
	 */
	@EJB
	protected IoPConfig configurator;
	
	/**
	 * Default constructor
	 */
	public IoPEndpointImpl() {}
	
	/**
	 * Constructor that sets the swarm rating bean
	 * 
	 * @param rater The Swarm Rating bean
	 */
	public IoPEndpointImpl(TorrentRating rater) {
		this.rater = rater;
	}
	
	/**
	 * Constructor that sets the configurator bean
	 * 
	 * @param configurator The Configurator bean
	 */
	public IoPEndpointImpl(IoPConfig configurator) {
		this.configurator = configurator;
	}
	
	/**
	 * Constructor that sets the swarm rating and configurator beans
	 * 
	 * @param rater The Swarm Rating and Configurator beans
	 */
	public IoPEndpointImpl(TorrentRating rater, IoPConfig configurator) {
		this.rater = rater;
		this.configurator = configurator;
	}

	/**
	 * Sets the current active torrents of the IoP, so that the IoP can be added
	 * as a preferred peer on a peer request list.
	 * 
	 * @param torrents The hashes of the torrents that the IoP currently participates 
	 * in, along with info about the number of peers to be returned.
	 *  
	 * @return Info (IP, port) about the local peers participating in each reported swarm.
	 */
	@Override
	@WebMethod
	public List<ResponseEntry> activeInTorrents(List<ActiveTorrent> torrents) {
		log.info("activeInTorrents called");
		
		/* List<ResponseEntry> res = new ArrayList<ResponseEntry>();
		
		ResponseEntry e = new ResponseEntry();
		e.setTorrentID("12345");
		
		List<PeerInfo> li = new ArrayList<PeerInfo>();
		PeerInfo i = new PeerInfo();
		i.setIpAddress("127.0.0.1");
		i.setPort(80);
		li.add(i);
		e.setPeers(li);
		
		res.add(e); */
		
		if (torrents != null && torrents.size() > 0) {
			List<ResponseEntry> res = this.rater.updateAndRetrieveSwarmInfo(torrents);
			return res;
		} else
			return null;
	}

	/**
	 * Returns torrent popularity statistics based on previous client requests.
	 * 
	 * @param maxTorrents The maximum number of torrent statistics.
	 * @return Torrent statistics
	 */
	@Override
	@WebMethod
	@WebResult(name = "stats", targetNamespace = "http://iop.ws.sis.smoothit.eu/")
	public List<TorrentStat> getTorrentStats(int maxTorrents) {
				
		log.info("getTorrentStats called");
		List<TorrentStat> res = this.rater.getRankedTorrents(maxTorrents);
		
		/* if (res == null){
			// Dummy response
			res = new ArrayList<TorrentStat>();
			
			TorrentStat e= new TorrentStat();
			e.setTorrentHash("12345");
			e.setRate(10);
			e.setTorrentURL("http://www.portal.primete.cy/torrents/A_movie.torrent");
			res.add(e);
		} */
										
		return res;
	}

	/**
	 * Receives the list of swarms a peer participates in as well as other related info .
	 * 
	 * @param report The activity report sent by a peer.
	 */
	@Override
	@WebMethod
	@WebResult(name = "activity", targetNamespace = "http://iop.ws.sis.smoothit.eu/")
	public void reportActivity(ActivityReport report) {
		
		log.info("reportActivity called");
		
		if (report != null) {
			log.info("New activity report received");
			log.info("Client's IP and port: " + report.getIpAddress() + ":" + Integer.toString(report.getPort()));
			
			if ((report.getEntries() != null) && (report.getEntries().size() > 0))
				for (ActivityReportEntry entry: report.getEntries())
					log.info("torrentID: " + entry.getTorrentID() + ", torrentURL: " + entry.getTorrentURL() + 
							", filesize: " + Double.toString(entry.getFileSize()) + ", progress" + Float.toString(entry.getProgress()));
			
			this.rater.storePeerActivity(report);
		}
		
	}
	
	/**
	 * Returns the configuration parameters for the IoP operation.
	 * 
	 * @param ipAddress The IP address of the IoP.
	 * 
	 * @return The configuration parameters for the IoP. 
	 */
	@Override
	@WebMethod
	@WebResult(name = "config", targetNamespace = "http://iop.ws.sis.smoothit.eu/")
	public ConfigParams getConfigParams(String ipAddress){
		
		/*  Dummy data for testing purposes. 
		
		ConfigParams res = new ConfigParams();
		res.setMode(SisWebInitializer.VALUE_IOP_OPERATION_MODE_COLLAB);
		res.setRemotes(true);
		res.setSlots(5);
		List<String> li = new ArrayList<String>();
		li.add("127.0.0.1");
		li.add("100.10.1.1");
		res.setLocalIPs(li);				
		res.setT(300);
		res.setUlow(512f);
		res.setDlow(1024f);
		res.setU(1024f);
		res.setD(2048f);
		res.setX(90f); */
		
		ConfigParams res = configurator.getIoPConfigParams(ipAddress);
		
		return res;
		
	}

}
